﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Controllers
{
    public class SignController : BaseController
    {
        //获取已提交表单的签核节点
        public ActionResult GetSignNodes(string formNo)
        {
            IQueryable<SignFlow> list = from r in ctx.SignFlows where r.FormNo == formNo select r;
            return Json(list);
        }

        //按登录人员获取 待其签核的所有表单
        public ActionResult GetSigningNodes()
        {
            EmpBasicInfo ebi = Session["ebi"] as EmpBasicInfo;
            int empId = ebi.Id;
            //最近45天申请的所有表单
            var v = (from r in ctx.Weeklies where r.CreatDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "周  报", r.EmpId, ReqDate=r.CreatDate })
                    .Concat(from r in ctx.ReqVehicleMains where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "用车申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqEvectionMains where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "出差申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqOvertimes where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "加班申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqVacationMains where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "请假申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqMeetingRooms where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "会议室申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqPerchaseMains where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "采购申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqReceptions where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "商务接待申请", r.EmpId, r.ReqDate })
                    .Concat(from r in ctx.ReqInvites where r.ReqDate >= DateTime.Today.AddDays(-45) select new { r.FormNo, ReqTypeName = "招聘申请", r.EmpId, r.ReqDate });
            //等待签核的表单
            var v2 = from r in v
                     where
                         (from r2 in ctx.SignFlows
                          where r2.IsCurrent == 1 && r2.CheckEmpId == empId
                          select r2.FormNo).Contains(r.FormNo) select r;
            var list = (from r in v2 join r2 in ctx.Employees on r.EmpId equals r2.Id orderby r.ReqDate descending select new ReqSignDTO { FormNo = r.FormNo, ReqTypeName = r.ReqTypeName, EmpId = r.EmpId, Name = r2.Name, ReqDate=r.ReqDate }).ToList();
            #region 打卡签核 start
            if (DateTime.Today.Day<7)
            {
                string ym = DateTime.Today.AddDays(-9).ToString("yyMM");
                if (ebi.Id == 360)//贾泽龙360
                {
                    int[] deptIds = { 29, 33, 48 };//安徽29,江苏33,四川48
                    var vt = from r in ctx.Employees
                             join r2 in ctx.EmpDepPositions on r.Id equals r2.EmpId
                             where r2.PosId > 7 && deptIds.Contains(r2.DeptId) && !(from r3 in ctx.SignFlows where r3.FormNo.Contains("Form_Card_") && r3.IsCurrent==0 select r3.FormNo.Substring(10,3)).Contains(r.Id.ToString())
                             select new ReqSignDTO { FormNo = "Form_Card_" + r.Id + ym, ReqTypeName = "打卡签核", EmpId = r.Id, Name = r.Name, ReqDate = DateTime.Today };
                    IEnumerable<ReqSignDTO> reqSignDtos = vt.ToList();
                    foreach(ReqSignDTO n in reqSignDtos)
                    {
                        SignFlow sf = ctx.SignFlows.SingleOrDefault(r => r.FormNo == n.FormNo);
                        if(sf==null)
                        {
                            sf = new SignFlow();
                            sf.FormNo =n.FormNo;
                            sf.CheckEmpId =ebi.Id;
                            sf.CheckNode = "经理";
                            sf.IsCurrent =1;
                            sf.OrderNo =1;
                            ctx.SignFlows.InsertOnSubmit(sf);
                        }
                    }
                    ctx.SubmitChanges();
                    list.AddRange(reqSignDtos);
                }
                else if (ebi.Id == 311)//徐擎311
                {
                    int[] deptIds = {26};//浙江26
                    var vt = from r in ctx.Employees
                             join r2 in ctx.EmpDepPositions on r.Id equals r2.EmpId
                             where r2.PosId > 7 && deptIds.Contains(r2.DeptId) && !(from r3 in ctx.SignFlows where r3.FormNo.Contains("Form_Card_" + ym) && r3.IsCurrent == 0 select r3.FormNo.Substring(10, 3)).Contains(r.Id.ToString())
                             select new ReqSignDTO { FormNo = "Form_Card_" + r.Id + ym, ReqTypeName = "打卡签核", EmpId = r.Id, Name = r.Name, ReqDate = DateTime.Today };
                    IEnumerable<ReqSignDTO> reqSignDtos = vt.ToList();
                    foreach (ReqSignDTO n in reqSignDtos)
                    {
                        SignFlow sf = ctx.SignFlows.SingleOrDefault(r => r.FormNo == n.FormNo);
                        if (sf == null)
                        {
                            sf = new SignFlow();
                            sf.FormNo = n.FormNo;
                            sf.CheckEmpId = ebi.Id;
                            sf.CheckNode = "经理";
                            sf.IsCurrent = 1;
                            sf.OrderNo = 1;
                            ctx.SignFlows.InsertOnSubmit(sf);
                        }
                    }
                    ctx.SubmitChanges();
                    list.AddRange(reqSignDtos);
                }
                else if (ebi.Id == 249)//徐东249
                {
                    int[] deptIds = {27};//辽宁27
                    var vt = from r in ctx.Employees
                             join r2 in ctx.EmpDepPositions on r.Id equals r2.EmpId
                             where r2.PosId > 7 && deptIds.Contains(r2.DeptId) && !(from r3 in ctx.SignFlows where r3.FormNo.Contains("Form_Card_" + ym) && r3.IsCurrent == 0 select r3.FormNo.Substring(10, 3)).Contains(r.Id.ToString())
                             select new ReqSignDTO { FormNo = "Form_Card_" + r.Id + ym, ReqTypeName = "打卡签核", EmpId = r.Id, Name = r.Name, ReqDate = DateTime.Today };
                    IEnumerable<ReqSignDTO> reqSignDtos = vt.ToList();
                    foreach (ReqSignDTO n in reqSignDtos)
                    {
                        SignFlow sf = ctx.SignFlows.SingleOrDefault(r => r.FormNo == n.FormNo);
                        if (sf == null)
                        {
                            sf = new SignFlow();
                            sf.FormNo = n.FormNo;
                            sf.CheckEmpId = ebi.Id;
                            sf.CheckNode = "经理";
                            sf.IsCurrent = 1;
                            sf.OrderNo = 1;
                            ctx.SignFlows.InsertOnSubmit(sf);
                        }
                    }
                    ctx.SubmitChanges();
                    list.AddRange(reqSignDtos);
                }
                else if (ebi.Id == 251)//程海涛251
                {
                    int[] deptIds = {28};//山东28
                    var vt = from r in ctx.Employees
                             join r2 in ctx.EmpDepPositions on r.Id equals r2.EmpId
                             where r2.PosId > 7 && deptIds.Contains(r2.DeptId) && !(from r3 in ctx.SignFlows where r3.FormNo.Contains("Form_Card_" + ym) && r3.IsCurrent == 0 select r3.FormNo.Substring(10, 3)).Contains(r.Id.ToString())
                             select new ReqSignDTO { FormNo = "Form_Card_" + r.Id + ym, ReqTypeName = "打卡签核", EmpId = r.Id, Name = r.Name, ReqDate = DateTime.Today };
                    IEnumerable<ReqSignDTO> reqSignDtos = vt.ToList();
                    foreach (ReqSignDTO n in reqSignDtos)
                    {
                        SignFlow sf = ctx.SignFlows.SingleOrDefault(r => r.FormNo == n.FormNo);
                        if (sf == null)
                        {
                            sf = new SignFlow();
                            sf.FormNo = n.FormNo;
                            sf.CheckEmpId = ebi.Id;
                            sf.CheckNode = "经理";
                            sf.IsCurrent = 1;
                            sf.OrderNo = 1;
                            ctx.SignFlows.InsertOnSubmit(sf);
                        }
                    }
                    ctx.SubmitChanges();
                    list.AddRange(reqSignDtos);
                }
            }
            #endregion

            IEnumerable<ReqSignDTO> examTypes = ctx.ExecuteQuery<ReqSignDTO>(string.Format(@"select 'Form_Exam_'+cast(Id as nvarchar(10)) as FormNo,'考试/调查' ReqTypeName,0 EmpId,'' Name,StartTime ReqDate
from ExamType a where ','+Testers+',' like '%,{0},%' and dateadd(mi,{1},StartTime)<=GETDATE() and EndTime>=GETDATE()
and exists(select 0 from ExamQuestions where TypeId=a.Id and Id not in(select QuestionId from ExamAnswers where EmpId={0}));", ebi.Id, -5));
            list.AddRange(examTypes);
            return Json(list);
        }

        //按登录人员获取 所有签核表单的状态(仅取按部门职位默认分配的权限表单)
        public ActionResult GetSignStatus()
        {
            EmpBasicInfo ebi = Session["ebi"] as EmpBasicInfo;
            int empId = ebi.Id;
            //最近14天申请的所有表单(保存状态除开)
            var v = (from r in ctx.Weeklies where r.StatusId!=0 && r.CreatDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "周  报", r.EmpId, ReqDate = r.CreatDate,r.StatusId })
                    .Concat(from r in ctx.ReqVehicleMains where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "用车申请", r.EmpId, r.ReqDate,r.StatusId })
                    .Concat(from r in ctx.ReqEvectionMains where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "出差申请", r.EmpId, r.ReqDate,r.StatusId })
                    .Concat(from r in ctx.ReqOvertimes where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "加班申请", r.EmpId, r.ReqDate,r.StatusId })
                    .Concat(from r in ctx.ReqVacationMains where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "请假申请", r.EmpId, r.ReqDate,r.StatusId })
                    .Concat(from r in ctx.ReqMeetingRooms where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "会议室申请", r.EmpId, r.ReqDate,r.StatusId })
                    .Concat(from r in ctx.ReqPerchaseMains where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "采购申请", r.EmpId, r.ReqDate,r.StatusId })
                    .Concat(from r in ctx.ReqReceptions where r.StatusId != 0 && r.ReqDate >= DateTime.Today.AddDays(-14) select new { r.FormNo, ReqTypeName = "商务接待申请", r.EmpId, r.ReqDate,r.StatusId });
            //权限部门或自己申请的表单
            List<int> sessionDeptIdList = Session["deptIdList"] as List<int>;
            //正在签或被退件的表单节点
            var v2 = from r in ctx.SignFlows where r.IsCurrent == 1 || r.IsPass == 0 select r;
            var list = from r in v
                     join r2 in ctx.EmpDepPositions on r.EmpId equals r2.EmpId
                     join r3 in ctx.Employees on r.EmpId equals r3.Id
                     join r4 in v2 on r.FormNo equals r4.FormNo
                     into t
                     from x in t.DefaultIfEmpty()
                       where sessionDeptIdList.Contains(r2.DeptId) || r.EmpId == empId || (ebi.Id == 254 && r.ReqTypeName == "用车申请")
                     orderby r.ReqDate descending
                     select new { r.FormNo, r.ReqTypeName, r.EmpId, r3.Name, r.ReqDate,r.StatusId,x.CheckNode };
            return Json(list.Distinct().OrderByDescending(r=>r.ReqDate));
        }

        //表单签核
        public ActionResult FormSign(int id, string comment, int isPass)//也可以在客户端构造签核节点,而传递一个json数据
        {
            var rdto = new ResultMessages();
            rdto.Message = "";
            try
            {
                SignFlow oriSignFlow = ctx.SignFlows.Single(r => r.Id == id);
                if(oriSignFlow.IsCurrent!=1)
                {
                    rdto.Message = "在您之前已有其他人签核该节点,您的签核将忽略!";
                    rdto.Result = false;
                }
                else
                {
                    var parallelSignFlows = ctx.SignFlows.Where(r => r.FormNo == oriSignFlow.FormNo && r.OrderNo == oriSignFlow.OrderNo&&r.IsCurrent==1);
                    foreach(SignFlow sf in parallelSignFlows)
                    {
                        sf.Comment = oriSignFlow.Checker + "已签核,系统自动忽略该节点";
                        sf.IsPass = isPass;
                        sf.IsCurrent = 0;
                    }

                    oriSignFlow.Comment = comment;
                    EmpBasicInfo ebi = Session["ebi"] as EmpBasicInfo;
                    string checker =ebi.Name;
                    if(checker=="杨明俊"|| checker=="张绪盛")
                        checker="行政部";
                    oriSignFlow.Checker = checker;
                    oriSignFlow.CheckDate = DateTime.Now;
                    oriSignFlow.IsPass = isPass;
                    oriSignFlow.IsCurrent = 0;

                    var nextSignFlows = ctx.SignFlows.Where(r => r.FormNo == oriSignFlow.FormNo && r.OrderNo == oriSignFlow.OrderNo + 1);
                    bool hasNext = nextSignFlows.Count()>0;
                    if (isPass == 1 && hasNext)//该节点通过,还存在下一个节点:将下一个节点置为 待签状态
                    {
                        foreach(SignFlow sf in nextSignFlows)
                        {
                            sf.IsCurrent = 1;
                        }
                    }
                    else if (isPass == 1)//该节点通过,不存在下一个节点:将表单置为 全通过状态
                    {
                        switch (oriSignFlow.FormNo.Substring(0, 9))
                        {
                            case "Form_Week"://周报
                                Weekly reqWeek = ctx.Weeklies.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqWeek.StatusId = 2;
                                break;
                            case "Form_Vehi"://用车申请
                                ReqVehicleMains reqVehi = ctx.ReqVehicleMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqVehi.StatusId = 2;//全通过
                                break;
                            case "Form_Evec"://出差申请
                                var reqEvec = ctx.ReqEvectionMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqEvec.StatusId = 2;//全通过
                                break;
                            case "Form_Over"://加班申请
                                var reqOver = ctx.ReqOvertimes.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqOver.StatusId = 2;//全通过
                                break;
                            case "Form_Vaca"://请假申请
                                var reqVaca = ctx.ReqVacationMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqVaca.StatusId = 2;//全通过
                                break;
                            case "Form_Meet"://会议室申请
                                var reqMeet = ctx.ReqMeetingRooms.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqMeet.StatusId = 2;//全通过
                                break;
                            case "Form_Perc"://采购申请
                                var reqPerh = ctx.ReqPerchaseMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqPerh.StatusId = 2;//全通过
                                break;
                            case "Form_Rece"://商务接待申请
                                var reqRece = ctx.ReqReceptions.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqRece.StatusId = 2;//全通过
                                break;
                            case "Form_Invi"://招聘申请
                                var reqInvi = ctx.ReqInvites.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqInvi.StatusId = 2;//全通过
                                break;
                            default:
                                break;
                        }
                    }
                    else//该节点退件:将表单置为 退件状态
                    {
                        switch (oriSignFlow.FormNo.Substring(0, 9))
                        {
                            case "Form_Week"://周报
                                Weekly reqWeek = ctx.Weeklies.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqWeek.StatusId = 3;
                                break;
                            case "Form_Vehi"://用车申请
                                var reqVehi = ctx.ReqVehicleMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqVehi.StatusId = 3;//退件
                                break;
                            case "Form_Evec"://出差申请
                                var reqEvec = ctx.ReqEvectionMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqEvec.StatusId = 3;//退件
                                break;
                            case "Form_Over"://加班申请
                                var reqOver = ctx.ReqOvertimes.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqOver.StatusId = 3;//退件
                                break;
                            case "Form_Vaca"://请假申请
                                var reqVaca = ctx.ReqVacationMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqVaca.StatusId = 3;//退件
                                break;
                            case "Form_Meet"://会议室申请
                                var reqMeet = ctx.ReqMeetingRooms.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqMeet.StatusId = 3;//退件
                                break;
                            case "Form_Perh"://采购申请
                                var reqPerh = ctx.ReqPerchaseMains.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqPerh.StatusId = 3;//退件
                                break;
                            case "Form_Rece"://商务接待申请
                                var reqRece = ctx.ReqReceptions.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqRece.StatusId = 3;//退件
                                break;
                            case "Form_Invi"://招聘申请
                                var reqInvi = ctx.ReqInvites.Single(r => r.FormNo == oriSignFlow.FormNo);
                                reqInvi.StatusId = 3;//退件
                                break;
                            default:
                                break;
                        }
                    }

                    ctx.SubmitChanges();
                    rdto.Message = "签核成功";
                    rdto.Result = true;
                }
            }
            catch (Exception ex)
            {
                rdto.Message = "签核失败";
                rdto.Result = false;
            }
            return Json(rdto);
        }

        //退签
        public ActionResult noPass( string formno)
        {
            EmpBasicInfo ebi = Session["ebi"] as EmpBasicInfo;
            if (ebi.Id == 187 || ebi.JobNo.ToLower() == "szap468")
            {
                var rdto = new ResultMessages();
                rdto.Message = "";
                try
                {
                    IQueryable<SignFlow> sfs = from q in ctx.SignFlows where q.FormNo == formno select q;
                    foreach (SignFlow sf in sfs)
                    {
                        sf.IsCurrent = 0;
                        sf.IsPass = 0;
                        if (sf.Checker != "行政部")
                        {
                            sf.Checker = "";
                        }
                        sf.CheckDate = DateTime.Now;
                    }
                    if (formno.IndexOf("Form_Vaca_") >= 0)//请假
                    {
                        ReqVacationMain req = ctx.ReqVacationMains.Single(q => q.FormNo == formno);
                        req.StatusId = 3;
                    }
                    else if (formno.IndexOf("Form_Evec_") >= 0)//出差
                    {
                        ReqEvectionMain req = ctx.ReqEvectionMains.Single(q => q.FormNo == formno);
                        req.StatusId = 3;
                    }
                    else if (formno.IndexOf("Form_Over_") >= 0)//加班
                    {
                        ReqEvectionMain req = ctx.ReqEvectionMains.Single(q => q.FormNo == formno);
                        req.StatusId = 3;
                    }
                    ctx.SubmitChanges();
                    rdto.Message = "签核成功";
                    rdto.Result = true;
                }
                catch
                {
                    rdto.Message = "签核失败";
                    rdto.Result = false;
                }
                return Json(rdto);
            }
            else
                return null;
        }
    }
}